package com.kifas.controller;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.kifas.entity.BarangEntity;
import com.kifas.entity.JenisBarangEntity;
import com.kifas.entity.PembelianDetailEntity;
import com.kifas.entity.PembelianEntity;
import com.kifas.entity.SatuanEntity;
import com.kifas.entity.SupplierEntity;
import com.kifas.model.xml.BarangModel;
import com.kifas.model.xml.JenisBarangModel;
import com.kifas.model.xml.PembelianDetailModel;
import com.kifas.model.xml.PembelianModel;
import com.kifas.model.xml.PersistStatus;
import com.kifas.model.xml.SatuanModel;
import com.kifas.model.xml.SupplierModel;
import com.kifas.service.EntityServiceManager;

@Component
@Scope("prototype")
@Path("/Pembelians")
public class PembelianController {

	private static Logger log = Logger.getLogger(PembelianController.class);

	@Context
	UriInfo uriInfo;

	@Autowired
	private EntityServiceManager entityManager;

	@GET
	@Produces(MediaType.TEXT_XML)
	public List<PembelianModel> getPembelians() {
		List<PembelianEntity> pembelianEntities = entityManager.getPembelians();
		return transformsList(pembelianEntities);
	}

	@POST
	@Produces(MediaType.APPLICATION_XML)
	@Consumes(MediaType.APPLICATION_XML)
	public PersistStatus insertPembelian(JAXBElement<PembelianModel> xml) {
		PembelianModel model = xml.getValue();
		PembelianEntity pembelian = new PembelianEntity();
		pembelian.setIdPembelian(null);
		SupplierEntity supplierEntity = entityManager.getSupplier(model.getSuplier().getIdSupplier());
		pembelian.setSupplier(supplierEntity);
		pembelian.setKeterangan(model.getKeterangan());
		pembelian.setNomorKontrakPembelian(model.getNomorKontrakPembelian());
		pembelian.setNomorPo(model.getNomorPo());
		pembelian.setTanggal(model.getTanggal());
		pembelian.setTanggalJatuhTempo(model.getTanggalJatuhTempo());
		pembelian.setClosed(model.isClosed());
		pembelian.setPajak(model.isPajak());
		pembelian.setKirim(model.isKirim());
		Set<PembelianDetailEntity> pembelianDetails = new HashSet<PembelianDetailEntity>();
		for (PembelianDetailModel modelDetail : model.getPembelianDetailModels()) {
			PembelianDetailEntity pembelianDetail = new PembelianDetailEntity();
			BarangEntity barang = entityManager.getBarang(modelDetail.getBarang().getIdBarang());
			pembelianDetail.setPembelian(pembelian);
			pembelianDetail.setIdDetailPembelian(null);
			pembelianDetail.setBarang(barang);
			pembelianDetail.setDiscount(modelDetail.getDiscount());
			pembelianDetail.setPajak(modelDetail.getPajak());
			pembelianDetail.setQty(modelDetail.getQty());
			pembelianDetail.setSubTotal(modelDetail.getSubTotal());
			pembelianDetail.setPrice(modelDetail.getPrice());
			pembelianDetails.add(pembelianDetail);
		}
		pembelian.setPembelianDetails(pembelianDetails);
		try {
			entityManager.persist(pembelian);
		} catch (Exception e) {
			return new PersistStatus("PembelianEntity", "failed", "can not save pembelian");
		}
		return new PersistStatus("PembelianEntity", "success");
	}

	@GET
	@Path("{id}")
	@Produces(MediaType.TEXT_XML)
	public PembelianModel getPembelian(@PathParam("id") Long idPembelian) {
		return transform(entityManager.getPembelian(idPembelian));
	}

	@GET
	@Path("Status/Open")
	@Produces(MediaType.TEXT_XML)
	public List<PembelianModel> getPembelianWitStatusOpen() {
		return transformsList(entityManager.getOpenPembelian());
	}

	@GET
	@Path("Status/Closed")
	@Produces(MediaType.TEXT_XML)
	public List<PembelianModel> getPembelianWithStatusClosed() {
		return transformsList(entityManager.getClosedPembelian());
	}

	@POST
	@Path("Status/Closed/{id}")
	@Produces(MediaType.TEXT_XML)
	public PersistStatus updatePembelianToClosed(@PathParam("id") Long idPembelian) {
		try {
			entityManager.updatePembelianToClosed(idPembelian);
		} catch (Exception e) {
			log.error("can not update pembelian", e);
			return new PersistStatus("PembelianEntity", "failed", "can not update pembelian");
		}
		return new PersistStatus("PembelianEntity", "success");
	}

	private List<PembelianModel> transformsList(List<PembelianEntity> pembelianEntities) {
		List<PembelianModel> pembelians = new ArrayList<PembelianModel>();
		for (PembelianEntity pembelianEntity : pembelianEntities) {
			pembelians.add(transform(pembelianEntity));
		}
		return pembelians;
	}

	private PembelianModel transform(PembelianEntity pembelianEntity) {
		List<PembelianDetailModel> pembelianDetails = new ArrayList<PembelianDetailModel>();
		List<PembelianDetailEntity> pembelianDetailEntities = entityManager.getPembelianDetails(pembelianEntity);

		SupplierEntity supplier = pembelianEntity.getSupplier();
		SupplierModel supplierModel = new SupplierModel(supplier.getIdSupplier(), supplier.getNamaSupplier(), supplier.getAlamat(), supplier.getNoTelp(),
				supplier.getNoFax(), supplier.getContactPerson(), supplier.getCreatedBy());
		for (PembelianDetailEntity pembelianDetailEntity : pembelianDetailEntities) {
			BarangEntity barangEntity = pembelianDetailEntity.getBarang();
			JenisBarangEntity jenisBarangEntity = barangEntity.getJenisBarang();
			SatuanEntity satuanEntity = barangEntity.getSatuan();
			JenisBarangModel jenisBarang = new JenisBarangModel(jenisBarangEntity.getIdJenisBarang(), jenisBarangEntity.getJenis(), jenisBarangEntity.getCreatedBy());
			SatuanModel satuan = new SatuanModel(satuanEntity.getIdSatuan(), satuanEntity.getSatuan(), satuanEntity.getCreatedBy());
			BarangModel barang = new BarangModel(barangEntity.getIdBarang(), barangEntity.getKdBarang(), jenisBarang, satuan, barangEntity.getNama(),
					barangEntity.getHargaBeli(), barangEntity.getHargaJual(), barangEntity.getCreatedBy());
			PembelianDetailModel pembelianDetailModel = new PembelianDetailModel(pembelianDetailEntity.getIdDetailPembelian(), barang, satuan,
					pembelianDetailEntity.getQty(), pembelianDetailEntity.getDiscount(), pembelianDetailEntity.getPajak(), pembelianDetailEntity.getPrice(),
					pembelianDetailEntity.getSubTotal(), pembelianDetailEntity.getCreatedBy());
			pembelianDetails.add(pembelianDetailModel);
		}
		return new PembelianModel(pembelianEntity.getIdPembelian(), pembelianEntity.getNomorPo(), pembelianEntity.getTanggal(), pembelianEntity.isKirim(),
				pembelianEntity.getKeterangan(), pembelianEntity.isPajak(), pembelianEntity.isClosed(), pembelianEntity.getTotal(),
				pembelianEntity.getBiayaLain(), supplierModel, pembelianEntity.getTanggalJatuhTempo(), pembelianEntity.getNomorKontrakPembelian(),
				new HashSet<PembelianDetailModel>(pembelianDetails), pembelianEntity.getCreatedBy(), pembelianEntity.getCreatedDate());
	}
}
